package com.yuyou.tas.admin.service.impl;

import com.yuyou.tas.admin.service.IAuthOrganizationFuncService;
import com.yuyou.tas.admin.service.IAuthRoleService;
import com.yuyou.tas.admin.service.IOfficeTokenService;
import com.yuyou.tas.service.api.admin.dto.OfficeTokenDTO;
import com.yuyou.tas.service.api.admin.entity.AuthRole;
import com.yuyou.tas.service.api.lesson.entity.BaseChapter;
import com.yuyou.tas.service.api.lesson.entity.LessonClassUserRel;
import com.yuyou.tas.service.api.lesson.entity.LessonResource;
import com.yuyou.tas.service.api.lesson.service.BaseChapterAPI;
import com.yuyou.tas.service.api.lesson.service.LessonClassAPI;
import com.yuyou.tas.service.api.lesson.service.LessonResourceAPI;
import com.yuyou.tas.util.bean.LoginRedisObj;
import com.yuyou.tas.util.bean.ResBoolSimpleInfo;
import com.yuyou.tas.util.config.SystemConfig;
import com.yuyou.tas.util.enums.admin.AuthRoleEnums;
import com.yuyou.tas.util.enums.lesson.LessonResourceEnums;
import com.yuyou.tas.util.exception.BusinessException;
import com.yuyou.tas.util.message.CommMess;
import com.yuyou.tas.util.office.edit.DateUtils;
import com.yuyou.tas.util.office.edit.Token;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class OfficeTokenServiceImpl implements IOfficeTokenService{

	
	private final String APP_ID="0001";
	
	@Autowired
	private LessonResourceAPI lessonResourceAPI;
	
	@Autowired
	private LessonClassAPI lessonClassAPI;
	@Autowired
	private BaseChapterAPI baseChapterAPI;
	
	@Autowired
	private IAuthRoleService authRoleService;
	
	@Autowired
	private IAuthOrganizationFuncService authOrganizationFuncService;
	
	@Override
	public ResBoolSimpleInfo<String> resFuncLim(Long organId,Integer type){
		//系统机构不受控制
		if(organId == SystemConfig.SYS_ORGAN_ID.longValue()){
			return ResBoolSimpleInfo.getSuccessInfo();
		}
		//预览或者null不受控制
		if(type==null){
			return ResBoolSimpleInfo.getSuccessInfo();
		}
		
		boolean res=authOrganizationFuncService.hasPermission(organId, type);
		if(!res){
			return ResBoolSimpleInfo.getFailInfo("没有权限");
		}
		return ResBoolSimpleInfo.getSuccessInfo();
	}
	
	@Override
	public ResBoolSimpleInfo<String> resPermLim(LoginRedisObj user,LessonResource lessonResource){
		//系统机构不受控制
		if(user.getOrganizationId() == SystemConfig.SYS_ORGAN_ID.longValue()){
			return ResBoolSimpleInfo.getSuccessInfo();
		}	
        BaseChapter bc=null;
        //班级课件讲次
        if(lessonResource.getLessonClassId()!=null){  	
        	if(lessonResource.getType().intValue()==LessonResourceEnums.type.course.getValue()){
        		 bc=baseChapterAPI.selectByCla7CourseUrl(lessonResource.getLessonClassId(), lessonResource.getResourceId());	
        	}
        	else if(lessonResource.getType().intValue()==LessonResourceEnums.type.lecture.getValue()){
        		 bc=baseChapterAPI.selectByCla7LectureUrl(lessonResource.getLessonClassId(), lessonResource.getResourceId());	
        	}       	
        }
      //讲次库课件讲次
        else{     	
           	if(lessonResource.getType().intValue()==LessonResourceEnums.type.course.getValue()){
        		 bc=baseChapterAPI.selectByCourseUrl(lessonResource.getResourceId());
        	}
        	else if(lessonResource.getType().intValue()==LessonResourceEnums.type.lecture.getValue()){
        		 bc=baseChapterAPI.selectByLectureUrl(lessonResource.getResourceId());
        	}        	
        }
        if(bc!=null){
            /*//找出机构的科目年级
            List<AuthOrganizationPermit>permitList=authOrganPermitService.findByOrganId(user.getOrganizationId(), null);

            List<Long> organSubjects=permitList.stream().filter(item ->item.getType().equals(1)).map(item-> item.getfId()).collect(Collectors.toList());
            //验证科目
            if(!organSubjects.contains(bc.getDataSubject())){
    			return ResBoolSimpleInfo.getFailInfo("没有科目权限");
            }
            
            List<Long> organSectionIds=permitList.stream().filter(item ->item.getType().equals(2)).map(item-> item.getfId()).collect(Collectors.toList()); 
            //验证年级
            if(!organSectionIds.contains(bc.getBaseSectionId())){
    			return ResBoolSimpleInfo.getFailInfo("没有年级权限");
            }*/

            if(user.getOrganSubSecMap() == null
					|| !user.getOrganSubSecMap().containsKey(bc.getDataSubject())){
				return ResBoolSimpleInfo.getFailInfo("没有科目权限");
			}

			if(CollectionUtils.isEmpty(user.getOrganSubSecMap().get(bc.getDataSubject()))
					|| !user.getOrganSubSecMap().get(bc.getDataSubject()).contains(bc.getBaseSectionId())){
				return ResBoolSimpleInfo.getFailInfo("没有年级权限");
			}

        }
		return ResBoolSimpleInfo.getSuccessInfo();
	}
	
	
	private void limint(LoginRedisObj user,String resourceId,Boolean checkStan) throws Exception{
		LessonResource lessonResource=lessonResourceAPI.selectByResourceId(resourceId);
		if(lessonResource==null){
			throw new BusinessException("资源不存在");
		}

		//机构功能限制
		ResBoolSimpleInfo<String> res=resFuncLim(user.getOrganizationId(),lessonResource.getType());
		if(!res.isSuccess()){
			throw new BusinessException(res.getMessage());
		}
		
		
		//机构科目年级约束
		resPermLim(user,lessonResource);
		
		
		
		//判断该资源是否标准资源
        List<AuthRole>roleList=authRoleService.findAuthRoleByUserId(lessonResource.getAuthUserId());		        
        long countC=roleList.stream().filter(authRole -> authRole.getRoleType()!=null && authRole.getRoleType()==AuthRoleEnums.roleType.system.getValue()).count();        
//        if(!checkStan && (countC>0 || lessonResource.getAuthUserId()==null)){	
        if(!checkStan && (countC>0)){	
        	return;      	
        }else{
			if(lessonResource.getAuthOrganizationId().longValue()!=user.getOrganizationId().longValue()){
				throw new BusinessException(CommMess.ERR_POWER);
			}
			//班级资源权限
			if(!user.getIsManager() && lessonResource.getLessonClassId()!=null){		
				List<LessonClassUserRel> cuList=lessonClassAPI.findByUserId(user.getUserId());			
				List<Long> classIdList=cuList.stream().map(itme -> itme.getLessonClassId()).collect(Collectors.toList());			
				if(!classIdList.contains(lessonResource.getLessonClassId())){
					throw new BusinessException(CommMess.ERR_POWER);
				}		
			}
        }
        
	}
	
	@Override
	public OfficeTokenDTO view(LoginRedisObj user,String resourceId) throws Exception {
		this.limint(user,resourceId,false);
		String token=Token.generate(APP_ID,resourceId, DateUtils.nowAddHour(24),Token.Permission.READ);
		OfficeTokenDTO OfficeTokenDTO=new OfficeTokenDTO();
		OfficeTokenDTO.setToken(token);
		OfficeTokenDTO.setResourceId(resourceId);
		return OfficeTokenDTO;
	}

	@Override
	public OfficeTokenDTO edit(LoginRedisObj user,String resourceId) throws Exception {
		this.limint(user,resourceId,true);
		String token=Token.generate(APP_ID,resourceId, DateUtils.nowAddHour(24),Token.Permission.READ,Token.Permission.WRITE);
		OfficeTokenDTO OfficeTokenDTO=new OfficeTokenDTO();
		OfficeTokenDTO.setToken(token);
		OfficeTokenDTO.setResourceId(resourceId);
		return OfficeTokenDTO;
	}
	
	@Override
	public OfficeTokenDTO editNoCheck(String resourceId) throws Exception {
		String token=Token.generate(APP_ID,resourceId, DateUtils.nowAddHour(24),Token.Permission.READ,Token.Permission.WRITE);
		OfficeTokenDTO OfficeTokenDTO=new OfficeTokenDTO();
		OfficeTokenDTO.setToken(token);
		OfficeTokenDTO.setResourceId(resourceId);
		return OfficeTokenDTO;
	}

	@Override
	public OfficeTokenDTO print(LoginRedisObj user,String resourceId) throws Exception {
		this.limint(user,resourceId,false);
		String token=Token.generate(APP_ID,resourceId, DateUtils.nowAddHour(24),Token.Permission.READ,Token.Permission.PRINT);
		OfficeTokenDTO OfficeTokenDTO=new OfficeTokenDTO();
		OfficeTokenDTO.setToken(token);
		OfficeTokenDTO.setResourceId(resourceId);
		return OfficeTokenDTO;
	}

	@Override
	public OfficeTokenDTO download(LoginRedisObj user,String resourceId) throws Exception {
		this.limint(user,resourceId,true);
		String token=Token.generate(APP_ID,resourceId, DateUtils.nowAddHour(24),Token.Permission.READ,Token.Permission.WRITE,Token.Permission.DOWNLOAD);
		OfficeTokenDTO OfficeTokenDTO=new OfficeTokenDTO();
		OfficeTokenDTO.setToken(token);
		OfficeTokenDTO.setResourceId(resourceId);
		return OfficeTokenDTO;
	}

}
